
#include "DBLoginHandler.h"
#include "CreatureManager.h"
#include "NetMapHandler.h"
#include "MapManager.h"
#include "GameConfig.h"
#include "ExpConfig.h"
#include "dbDataBase.h"

extern RECV_MSG_LOGIN_MAINSERVICE gMsgLoginMainService;
extern RECV_MSG_CREATEACCOUNT gMsgCreatePlayer;
extern RECV_MSG_CREATEROLE gMsgCreateRole;
extern RECV_MSG_ROLE_INFO gMsgRoleInfo;

extern dbIDatabase* gDBServer;

fvoid		DB_Creat_Account( dbResult* result )
{
	if ( !result )
		return;

	GamePlayer* player = static_cast< GamePlayer* >( result->pData );
	if ( player == F_NULL )
		return;

	if ( !player->IsValid() )
		return;


	dbIRecordset* pRes =  result->pResult;
	dbIRecord* tempRecord = F_NULL;

	if( !pRes )
		return;

	fint32 RecordCount = pRes->CountRecord();

	if ( RecordCount == 0 )
	{
		//@ db error?
		return;
	}
	else
	{
		tempRecord = pRes->GetRecord();
		fint64 b = (fint64)tempRecord->Field( (fuint32)0 );

		gMsgCreatePlayer.Error = !b;

		player->PackMsg( &gMsgCreatePlayer );
		player->SendMsg();
	}
}


fvoid		DB_Creat_Role( dbResult* result )
{
	if ( !result )
		return;

	GamePlayer* player = static_cast< GamePlayer* >( result->pData );
	if ( player == F_NULL )
		return;

	dbIRecordset* pRes =  result->pResult;
	dbIRecord* tempRecord = F_NULL;

	if( !pRes )
		return;

	tempRecord = pRes->GetRecord();

	fint32 error = tempRecord->Field( (fuint32)0 );

	if ( error )
	{
		gMsgCreateRole.Error = error;

		player->PackMsg( &gMsgCreateRole );
		player->SendMsg();
	}
	else
	{
		gMsgLoginMainService.Stage = 0;
		
		gMsgRoleInfo.Data = player->GetData();
		gMsgRoleInfo.Data.Base = player->GetFightData().Base;
		
		gMsgRoleInfo.ItemNum = 0;
		gMsgRoleInfo.Stone = 10000;
		gMsgRoleInfo.size = 12 + sizeof( CreatureData ) + gMsgRoleInfo.ItemNum * sizeof( ItemInfo );

		player->PackMsg( &gMsgLoginMainService );
		player->PackMsg( &gMsgRoleInfo );

		gMapManager->EnterScene( player );

		player->SendMsg();
	}

	
}


fvoid		DB_Update_QuitGame( dbResult* result )
{
	if ( !result )
		return;

	GamePlayer* player = static_cast< GamePlayer* >( result->pData );
	if ( player == F_NULL )
		return;

	//logManager::Print( "DB_Update_QuitGame guid=%d " , player->GetGUID() );


	gCreatureManager->ReleasePlayer( player );
	gCreatureManager->RemovePlayer( player );
	player->Release();
}


fvoid		DB_Update_Pet( dbResult* result )
{
	

	
}

static fint32 gGuestID = GUEST_GUID;


fvoid		DB_Guest( GamePlayer* player )
{
	CreatureData& data = player->GetData();
	data = gGameConfig->GuestData;
	data.NEXTEXP = gExpConfig->EXP[ data.Level + 1 ];

	gGuestID++;

	fbool bload = gCreatureManager->SetGUID( gGuestID , player );

	STRCPY( data.Name , "GUEST" );
	STRCPY( data.Name + 5 , ITOA( gGuestID ) ) ;

	player->GetMoveData().Pos = gGameConfig->LoginMapPos;

	player->InitBaseData();
	player->UpdateFightData();

	player->GetFightData().Base.HP = player->GetFightData().Base.MAXHP;
	player->GetFightData().Base.MP = player->GetFightData().Base.MAXMP;

	gMsgLoginMainService.Stage = 0;
	
	gMsgRoleInfo.Data = data;
	gMsgRoleInfo.Data.Base = player->GetFightData().Base;

	gMsgRoleInfo.ItemNum = 0;
	gMsgRoleInfo.Stone = 10000;
	gMsgRoleInfo.size = 12 + sizeof( CreatureData ) + sizeof( MapPos ) + gMsgRoleInfo.ItemNum * sizeof( ItemInfo );

	player->PackMsg( &gMsgLoginMainService );
	player->PackMsg( &gMsgRoleInfo );

	gMapManager->EnterScene( player );

	player->SendMsg();
}


fvoid		DB_Select_AccountInfo( dbResult* result )
{
	if ( !result )
		return;

	GamePlayer* player = static_cast< GamePlayer* >( result->pData );
	if ( player == F_NULL )
		return;

	if ( !player->IsValid() )
		return;

	dbIRecordset* pRes =  result->pResult;
	dbIRecord* tempRecord = F_NULL;

	if( !pRes )
		return;

	fint32 RecordCount = pRes->CountRecord();

	if ( RecordCount == 0 )
	{
		gMsgLoginMainService.Stage = 1;
		
		player->PackMsg( &gMsgLoginMainService );
		player->SendMsg();
		
		return;
	}
	else
	{
		tempRecord = pRes->GetRecord();

		STRCPY( player->Account , tempRecord->Field( (fuint32)0 )  );

		SPRINTF( SQL_BUFFER , SQL_SELECT_ROLE_INFO.c_str() , (fbyte*)tempRecord->Field( (fuint32)0 ) );
		
        gDBServer->ExecuteAsyncSQL( SQL_BUFFER , player , DB_Select_RoleInfo );
	}

}


fvoid		DB_Select_PetInfo( dbResult* result )
{
	if ( !result )
		return;

	GamePlayer* player = static_cast< GamePlayer* >( result->pData );
	if ( player == F_NULL )
		return;

	if ( !player->IsValid() )
		return;

	dbIRecordset* pRes =  result->pResult;
	dbIRecord* tempRecord = F_NULL;

	if( !pRes )
		return;

	GamePetMap& petMap = player->GetPetMap();
	GamePetMap& petHomeMap = player->GetPetAtHomeMap();

	if ( !petMap.empty() || !petHomeMap.empty() )
	{
		assert( 0 );
		return;
	}

	fint32 RecordCount = pRes->CountRecord();

	for ( fint32 i = 0 ; i < RecordCount ; i++ )
	{
		pRes->Move( i );

		tempRecord = pRes->GetRecord();

		fint32 petID = tempRecord->Field( (fuint32)0 );

		STRCPY( SQL_BUFFER , tempRecord->Field( 2 ) );
		SQL_BUFFER[ MAX_SQL_BUFFER - 1 ] = '\0';

		fint32 type = atoi( SQL_BUFFER );
		fbyte* pc = strchr( SQL_BUFFER , ',' );pc++;

		fint32 id = atoi( pc );
		pc = strchr( pc , ',' );pc++;

		GameEnemy* enemy = gCreatureManager->GetEnemy( id );
		GamePet* pet;

		if ( type == GPT_HOME )
		{
			pet = &petHomeMap[ petID ];
		}
		else
		{
			pet = &petMap[ petID ];
		}

		pet->Init( enemy );
		pet->SetGUID( petID );
		pet->SetPetType( (GamePetType)type );

		if ( type == GPT_ATTACK )
		{
			player->SetAttackPet( pet );
		}

		CreatureData& data = pet->GetData();
		CreatureFightData& fightData = pet->GetFightData();
		PetData& petData = pet->GetPetData();

		STRCPY( data.Name , tempRecord->Field( 1 ) );

		data.ActionID = pet->GetEnemyBase()->intValue[ GEBIV_ROLE ];
		data.Level = (fubyte)atoi( pc );
		pc = strchr( pc , ',' );pc++;
		data.EXP = atoi( pc );
		pc = strchr( pc , ',' );pc++;
		petData.LevelUpPoint = (freal32)atof( pc );
		pc = strchr( pc , ',' );pc++;
		petData.Vitality = (freal32)atof( pc );
		data.Vitality = petData.Vitality;
		pc = strchr( pc , ',' );pc++;
		petData.Strength = (freal32)atof( pc );
		data.Strength = petData.Strength;
		pc = strchr( pc , ',' );pc++;
		petData.Toughness = (freal32)atof( pc );
		data.Toughness = petData.Toughness;
		pc = strchr( pc , ',' );pc++;
		petData.Dexterity = (freal32)atof( pc );
		data.Dexterity = petData.Dexterity;
		pc = strchr( pc , ',' );pc++;
		data.Base.Charm = (fbyte)atoi( pc );
		pc = strchr( pc , ',' );pc++;
		fightData.Base.HP = (fint16)atoi( pc );
		pc = strchr( pc , ',' );pc++;
		fightData.Base.MP = (fint16)atoi( pc );
		pc = strchr( pc , ',' );pc++;

		data.NEXTEXP = gExpConfig->EXP[ data.Level + 1 ];

		pet->InitBaseData();
		pet->UpdateFightData();

		fightData.Base.HP = fightData.Base.MAXHP;
		fightData.Base.MP = fightData.Base.MAXMP;
	}
	
	gMsgLoginMainService.Stage = 0;
	
	gMsgRoleInfo.Data = player->GetData();
	gMsgRoleInfo.Data.Base = player->GetFightData().Base;
	gMsgRoleInfo.ItemNum = 0;

	ItemBag& bag = player->GetItemBag();

	for ( fint32 i = 0 ; i < SAET_COUNT ; ++i )
	{
		ItemData* data = bag.GetEquip( i ).GetData();
		fint32 num = bag.GetEquip( i ).GetNum();
		if ( data )
		{
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Item = 0;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Type = data->Type;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].ID = data->ID;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Image = data->Img;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Sell = data->Sell;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Num = num;

			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Px = data->Px;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Py = data->Py;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].i = i;

			gMsgRoleInfo.ItemNum++;
		}
	}

	for ( fint32 i = 0 ; i < MAX_ITEM ; ++i )
	{
		ItemData* data = bag.GetItem( i ).GetData();
		fint32 num = bag.GetItem( i ).GetNum();
		if ( data )
		{
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Item = 1;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Type = data->Type;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].ID = data->ID;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Image = data->Img;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Sell = data->Sell;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Num = num;

			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Px = data->Px;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].Py = data->Py;
			gMsgRoleInfo.Item[ gMsgRoleInfo.ItemNum ].i = i;

			gMsgRoleInfo.ItemNum++;
		}
	}

	gMsgRoleInfo.Stone = player->mStone;
	gMsgRoleInfo.size = 12 + sizeof( CreatureData ) + sizeof( MapPos ) + gMsgRoleInfo.ItemNum * sizeof( ItemInfo );

	player->PackMsg( &gMsgLoginMainService );
	player->PackMsg( &gMsgRoleInfo );

	gMapManager->EnterScene( player );

	player->SendMsg();
}


fvoid		DB_Select_RoleInfo( dbResult* result )
{
	if ( !result )
		return;

	GamePlayer* player = static_cast< GamePlayer* >( result->pData );
	if ( player == F_NULL )
		return;

	if ( !player->IsValid() )
		return;

	dbIRecordset* pRes =  result->pResult;
	dbIRecord* tempRecord = F_NULL;

	if( !pRes )
		return;

	fint32 RecordCount = pRes->CountRecord();

	if ( RecordCount == 0 )
	{
		//@ create role

		gMsgLoginMainService.Stage = 2;

		player->PackMsg( &gMsgLoginMainService );
		player->SendMsg();

		return;
	}

	//@ login

	pRes->Move(0);

	tempRecord = pRes->GetRecord();

	fint32 guid = tempRecord->Field( (fuint32)0);
	fbool bload = gCreatureManager->SetGUID( guid , player );

	if ( !bload )
	{
		//@ load again

		player->GetSocket()->Close();

		GamePlayer* oldPlayer = gCreatureManager->GetPlayer( guid );
		oldPlayer->GetSocket()->Close();

		return;
	}

	SPRINTF( SQL_BUFFER , SQL_SELECT_PET_INFO.c_str() , player->GetGUID() );
	gDBServer->ExecuteAsyncSQL( SQL_BUFFER , player , DB_Select_PetInfo );


	CreatureData& data = player->GetData();
	CreatureFightData& fightData = player->GetFightData();


	STRCPY( data.Name , tempRecord->Field( 1 )  );

	player->SetType( (GameCreature::GameCreatureType)(fint32)tempRecord->Field( 4 ) );
	STRCPY( SQL_BUFFER , tempRecord->Field( 2 ) );
	SQL_BUFFER[ MAX_SQL_BUFFER - 1 ] = '\0';

	player->GetMoveData().Pos.MapID = atoi( SQL_BUFFER );
	fbyte* pc = strchr( SQL_BUFFER , ',' );pc++;
	player->GetMoveData().Pos.Grid.x = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	player->GetMoveData().Pos.Grid.y = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Level = (fubyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.LevelPRO = (fubyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.LevelUpPoint = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.EXP = atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Vitality = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Strength = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Toughness = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Dexterity = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Base.Charm = (fbyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	fightData.Base.HP = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	fightData.Base.MP = (fint16)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Role = (fbyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Color = (fbyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Eye = (fbyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Mouth = (fbyte)atoi( pc );

	pc = strchr( pc , ',' );pc++;
	data.Base.Earth = (fbyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Base.Water = (fbyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Base.Fire = (fbyte)atoi( pc );
	pc = strchr( pc , ',' );pc++;
	data.Base.Wind = (fbyte)atoi( pc );
	
	pc = strchr( pc , ',' );pc++;
	player->mStone = atoi( pc );
	


	data.NEXTEXP = gExpConfig->EXP[ data.Level + 1 ];



	STRCPY( SQL_BUFFER , tempRecord->Field( 3 ) );
	SQL_BUFFER[ MAX_SQL_BUFFER - 1 ] = '\0';

	ItemBag& bag = player->GetItemBag();
	pc = SQL_BUFFER;

	for ( fint32 i = 0 ; i < SAET_COUNT ; ++i )
	{
		fint32 id = atoi( pc );
		pc = strchr( pc , '|' );pc++;
		fint32 num = atoi( pc );
		pc = strchr( pc , ',' );pc++;

		if ( id != INVALID_ID )
		{
			bag.GetEquip( i ).Init( id , num );
		}
	}

	for ( fint32 i = 0 ; i < MAX_ITEM ; ++i )
	{
		fint32 id = atoi( pc );
		pc = strchr( pc , '|' );pc++;
		fint32 num = atoi( pc );
		pc = strchr( pc , ',' );pc++;

		if ( id != INVALID_ID )
		{
			bag.GetItem( i ).Init( id , num );
		}
	}


	player->InitBaseData();
	player->UpdateFightData();


	fightData.Base.HP = fightData.Base.MAXHP;
	fightData.Base.MP = fightData.Base.MAXMP;

}

